package com.dingwen.treasure.kettle.utils;

import com.dingwen.treasure.kettle.constant.SuppressWarningConstant;
import org.reflections.Reflections;
import org.reflections.scanners.SubTypesScanner;
import org.reflections.util.ConfigurationBuilder;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Set;

/**
 * 　ReflectUtil: 反射工具类
 * 　@author dingwen
 * 　@date 2022/6/21
 */
@SuppressWarnings(SuppressWarningConstant.ALL)
public class ReflectUtil {

    /**
     * 获取泛型字节码
     *
     * @param order  顺序泛型类的泛型顺序，默认从0开始
     * @param object 对象
     * @return {@link Class}<{@link T}>
     */
    public static <T> Class<T> getClassForGeneric(Integer order, Object object) {
        Type superClass = object.getClass().getGenericSuperclass();
        Type[] actualTypeArguments = ((ParameterizedType) superClass).getActualTypeArguments();
        return (Class<T>) actualTypeArguments[order];
    }

    /**
     * 按父类获取子类
     *
     * @param subClass    子类
     * @param scanPackage 扫描路径
     * @return {@link Class}<{@link T}>
     */
    public static <T> Set<Class<T>> getSubclassesBySubClass(Class subClass, String scanPackage) {
        // 获取实现类
        ConfigurationBuilder configurationBuilder = new ConfigurationBuilder();
        configurationBuilder.forPackage(scanPackage);
        configurationBuilder.addScanners(new SubTypesScanner());
        Reflections reflections = new Reflections(configurationBuilder);
        return reflections.getSubTypesOf(subClass);
    }
}
